﻿#include "ssLog.h"
#ifdef SS_USE_WINDOWS
#include <windows.h>
#include <direct.h>
#else
#include <sys/stat.h>
#endif
#include "../time/ssTime.h"


namespace StarSeeker
{

ssLog::ssLog(u8 type, const char* path)
	:m_buffer(LOG_STR_LEN)
{
	memset(m_lastDate, 0, sizeof(m_lastDate));
	m_pFile = 0;
	m_info.GetInfo();
	if (path)
	{
		m_folder = path;
	} 
	else
	{
		m_folder = "./";
		m_folder += m_info.m_name;
		m_folder += "_logs";
	}
	m_subsection = type == 1 ? 1 : 0;
}

ssLog::~ssLog()
{
	CloseFile();
}

void ssLog::PrintDebug(const char *pLogString)
{
#ifndef SS_NONE_PRINT
	FormatString(0, pLogString);
#ifdef SS_USE_WINDOWS
	::OutputDebugStringA(m_buffer.GetString());
#endif
	::printf(m_buffer.GetString());
#endif
}

void ssLog::PrintDebugEx(const char *pLogString, ...)
{
#ifndef SS_NONE_PRINT
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(0, pLogString, arglist);
	va_end(arglist);
#ifdef SS_USE_WINDOWS
	::OutputDebugStringA(m_buffer.GetString());
#endif
	::printf(m_buffer.GetString());
#endif
}

void ssLog::Print(const char *pLogString)
{
	FormatString(1, pLogString);
	printf(m_buffer.GetString());
	SaveToFile(m_buffer.GetString());
}

void ssLog::PrintEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(1, pLogString, arglist);
	va_end(arglist);
	printf(m_buffer.GetString());
	SaveToFile(m_buffer.GetString());
}

void ssLog::Error(const char *pLogString)
{
	FormatString(3, pLogString);
	printf(m_buffer.GetString());
	SaveToFile(m_buffer.GetString());
}

void ssLog::ErrorEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(3, pLogString, arglist);
	va_end(arglist);
	printf(m_buffer.GetString());
	SaveToFile(m_buffer.GetString());
}

void ssLog::PrintFile(const char *pLogString)
{
	FormatString(2, pLogString);
	SaveToFile(m_buffer.GetString());
}

void ssLog::PrintFileEx(const char *pLogString, ...)
{
	va_list arglist;
	va_start(arglist, pLogString);
	FormatStringEx(2, pLogString, arglist);
	va_end(arglist);
	SaveToFile(m_buffer.GetString());
}
// 保存到文件
void ssLog::SaveToFile(const char * pStr)
{
	//是否新建文件
	MakeDir();

	CloseFile();
	m_pFile = ::fopen(m_filePath.GetString(), "a");
	if (m_pFile)
	{
		::fprintf(m_pFile, pStr);
		::fclose(m_pFile);
		m_pFile = 0;
	}
}
// 打开文件流
void ssLog::MakeDir()
{
	bool change = false;
	char szTime[32] = { 0 };
	if (m_subsection==1)
	{
		ssTime::GetLocalTimeYMDH(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMDH(m_lastDate);
			change = true;
		}
	} 
	else
	{
		ssTime::GetLocalTimeYMD(szTime);
		if (strcmp(szTime, m_lastDate))
		{
			ssTime::GetLocalTimeYMD(m_lastDate);
			change = true;
		}
	}
	if (change)
	{
		//建立logs文件夹
#ifdef SS_USE_WINDOWS
		::_mkdir(m_folder.GetString());
#else
		::mkdir(m_folder.GetString(), S_IRWXU);
#endif
		//建立日期文件
		m_filePath = m_folder;
		m_filePath += "/";
		m_filePath += m_lastDate;
		m_filePath += ".log";
	}
}
// 关闭文件
void ssLog::CloseFile()
{
	if (m_pFile)
	{
		::fclose(m_pFile);
		m_pFile = 0;
	}
}

void ssLog::FormatString(char lv, const char* str)
{
	char tempTime[LOG_TIME_LEN] = { 0 };
	ssTime::GetLocalTimeHMS(tempTime);
	m_buffer.Format("[%s]", tempTime);
	if (lv == 3)
		m_buffer += "[ERROR]";
	m_buffer += str;
	m_buffer += "\n";
}

// 格式化字符串
void ssLog::FormatStringEx(char lv, const char* str, va_list &vaList )
{
	char tempTime[LOG_TIME_LEN] = {0};
	char tempBuf[LOG_STR_LEN*2] = {0};
	ssTime::GetLocalTimeHMS(tempTime);
	m_buffer.Format("[%s]", tempTime);
	if (lv == 3)
		m_buffer += "[ERROR]";
	// 处理变长参数
	int len = vsnprintf(tempBuf, LOG_STR_LEN * 2 - 1, str, vaList);
	if (len <= 0)
	{
		m_buffer += "vsnprintf error!";
	}
	else
	{
		m_buffer += tempBuf;
	}
	m_buffer += "\n";
}

}
